Lambdaでの手軽な検証用にActionsでboto3用Lambda Layerを定期更新してみる
AWS上の複数サービスを連携させた処理を行いたい時やとりあえず一回手軽く動かしてみたいなーと思った場合、boto3を準備する手間に目を瞑るとAWS Lambdaがとても便利です。今ではMWAAという選択肢もありそうですが、これはこれでDAGの実装に一手間かかります。
boto3がLambda Layerへ勝手に仕込まれるようにしておけば、管理コンソール上からでもLambda関数化する際にLayerを使うように指定するだけで色々実験は可能だろうという目論見で、GitHub Actions上からboto3用のLambda Layer定期更新のWorkflowを組んでみることにしました。
ローカルの事前設定
homebrewで以下ライブラリをインストールしておきます。
brew install pyenv brew install pipenv brew install direnv
必要なバージョンのPythonのインストールも行っておきます。今回はGitHub ActionsのホストランナーUbuntu-20.04のPythonバージョンに合わせて3.8.10にしています。
専用リポジトリのセットアップ
GitHub上に以下のような設定でリポジトリを作成してcloneします。
git clone git@github.com:xxxxxxxx/boto3_layer.git
次にPipfile.lock作成のため、pipenv用設定の追加と仮想環境のセットアップを行います。
cd boto3_layer/ echo "3.8.10" >> .python-version echo "export PIPENV_VENV_IN_PROJECT=true" >> .envrc echo "layout pipenv" >> .envrc pipenv install boto3 direnv allow .
これで必要なPipfile.lockが作成されました。
Lambda Layerの作成
次にLambda Layerの作成です。上記でセットアップしたvenvが存在するとlayerの作成がし辛いため仮想環境を一度削除します。
pipenv --rm
layer用のzipファイルを作成してアップします。
mkdir layer/ PIP_TARGET=./layer pipenv sync zip -r boto3.zip ./layer export AWS_PROFILE=XXXXX aws lambda publish-layer-version --layer-name boto3 --zip-file fileb://boto3.zip --compatible-runtimes python3.8
以下実行ログ。
% mkdir layer/ % PIP_TARGET=./layer pipenv sync % zip -r boto3.zip ./layer adding: layer/ (stored 0%) adding: layer/boto3-1.18.37.dist-info/ (stored 0%) adding: layer/boto3-1.18.37.dist-info/RECORD (deflated 60%) adding: layer/boto3-1.18.37.dist-info/LICENSE (deflated 65%) adding: layer/boto3-1.18.37.dist-info/WHEEL (stored 0%) ... % export AWS_PROFILE=XXXXX % aws lambda publish-layer-version --layer-name boto3 --zip-file fileb://boto3.zip --compatible-runtimes python3.8 { "Content": { "Location": "https://awslambda-ap-ne-1-layers.s3.ap-northeast-1.amazonaws.com/snapshots/....", "CodeSha256": "......", "CodeSize": 9523215 }, "LayerArn": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXX:layer:boto3", "LayerVersionArn": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXX:layer:boto3:1", "Description": "", "CreatedDate": "2021-09-08T07:28:12.932+0000", "Version": 1, "CompatibleRuntimes": [ "python3.8" ] }
これでローカルからの作成は完了しました。
定期更新させる
次に定期的にLayerを更新させるようにします。まずはpipenv関係のコミット。
echo "layer/" >> .gitignore git add -f Pipfile Pipfile.lock .envrc .python-version .gitignore git commit -m'add pipfile settings' git push origin HEAD
次にGitHub Actions用Workflowの作成を行います。
mkdir .github/workflows/ vim .github/workflows/layer_update.yml git add .github/workflows/layer_update.yml git push origin HEAD
layer_update.yml
の内容は以下の通り。
name: UpdateBoto3Layer on: workflow_dispatch: schedule: - cron: '0 0 * * *' jobs: update: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v1 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: ap-northeast-1 - name: Install pipenv shell: bash run: | python -m pip install --upgrade pip python -m pip install pipenv - name: Upload Lambda Layer run: | mkdir layer/ PIP_TARGET=./layer pipenv sync zip -r boto3.zip ./layer aws lambda publish-layer-version --layer-name boto3 --zip-file fileb://boto3.zip --compatible-runtimes python3.8
実行するとLayerとしてboto3が追加可能になり、追加後は関数内でimport可能になります。
import boto3 def lambda_hundler(event, context): return { 'status': 'ok' }
あとがき
boto3のimport用にcdkでスタックを作成するのも過剰かと思い、一番手軽に且つ定期的にアップできる手段を考えて見た結果今回の方法に至りました。
特にboto3に限ったものではないため、必要な共有ライブラリの更新手段として活用するのも一つの手です。